package com.liujg.future.service;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.google.common.collect.Lists;
import com.liujg.future.config.MinioConfig;
import com.liujg.future.constant.ShopConstants;
import com.liujg.future.mapper.*;
import com.liujg.future.model.dto.*;
import com.liujg.future.model.entity.*;
import com.liujg.future.model.resp.*;
import com.liujg.future.util.JwtTokenUtils;
import com.liujg.future.util.KeyGenerator;
import com.liujg.future.util.MinioClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 店铺前台服务
 */
@Service
@Slf4j
public class ShopFrontService  {



    @Autowired
    private ShopBannerRepository shopBannerRepository;

    @Autowired
    private ShopCategoryRepository shopCategoryRepository;

    @Autowired
    private ShopHotRepository shopHotRepository;

    @Autowired
    private ShopHotDetailRepository shopHotDetailRepository;
    @Autowired
    private ShopHotDetailGoodsRepository shopHotDetailGoodsRepository;

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private AddressRepository addressRepository;

    @Autowired
    private ShopGuessLikeRepository shopGuessLikeRepository;
    @Autowired
    private ShopCategoryTopRepository shopCategoryTopRepository;

    @Autowired
    private ShopGoodsDetailRepository shopGoodsDetailRepository;

    @Autowired
    private CartRepository cartRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private KeyGenerator keyGenerator;

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClientUtils minioClientUtils;


    public List<Banner> banners(){
        return shopBannerRepository.findAll();
    }

    public List<Category> homeCategory(){
        return shopCategoryRepository.findAll();
    }


    public List<Hot> homeHot() {

        return shopHotRepository.findAll();
    }

    public PageVO<GuessLike> guessLike(PageDTO pageDTO) {

        Pageable pageable = PageRequest.of(pageDTO.getPage()-1, pageDTO.getPageSize());
        Page<GuessLike> page = shopGuessLikeRepository.findAll(pageable);

        PageVO<GuessLike> pageVO = new PageVO<>();
        pageVO.setCount((int)page.getTotalElements());
        pageVO.setPage(page.getNumber()+1);
        pageVO.setPageSize(pageDTO.getPageSize());
        pageVO.setPages(page.getTotalPages());
        if (!CollectionUtils.isEmpty(page.getContent())) {
            pageVO.setItems(page.getContent());
        }
        return pageVO;
    }

    public List<CategoryTop> categoryTop() {
        return shopCategoryTopRepository.findAll();
    }

    public GoodsDetail goodsDetail(String id) {
        return shopGoodsDetailRepository.findById(id).orElse(null);
    }

    public LoginVO wxMinSimpleLogin(LoginDTO loginDTO) {


        List<UserInfo> list = userInfoRepository.findByMobile(loginDTO.getPhoneNumber());
        if(CollectionUtils.isEmpty(list)){
            // 创建用户
            UserInfo userInfo = new UserInfo();
            userInfo.setId(String.valueOf(keyGenerator.generateKey().longValue()));
            userInfo.setMobile(loginDTO.getPhoneNumber());
            userInfo.setNickname("用户"+loginDTO.getPhoneNumber());
            userInfo.setAccount("用户"+loginDTO.getPhoneNumber());
            userInfo.setAvatar(ShopConstants.AVATAR_IMG);
            userInfoRepository.insert(userInfo);
            list = userInfoRepository.findByMobile(loginDTO.getPhoneNumber());
        }
        UserInfo userInfo = list.get(0);
        LoginVO loginVO = new LoginVO();

        // 生成tokenId;
        Map<String, String> jwtMap = new HashMap<>();
        jwtMap.put("userId", userInfo.getId());
        jwtMap.put("expire", String.valueOf(System.currentTimeMillis() + (30 * 24 * 60L * 60L * 1000L)));
        String tokenId = JwtTokenUtils.getToken(jwtMap);

        // 封装返回数据
        loginVO.setToken(tokenId);
        loginVO.setMobile(userInfo.getMobile());
        loginVO.setAccount(userInfo.getAccount());
        loginVO.setAvatar(userInfo.getAvatar());
        loginVO.setNickname(userInfo.getNickname());
        loginVO.setId(userInfo.getId());
        return loginVO;
    }

    public UserInfo memberProfile(String userId) {
        Optional<UserInfo> optional = userInfoRepository.findById(userId);
        return optional.get();
    }

    public UserInfo memberProfileModify(String userId,UserInfoDTO dto) {
        UserInfo userInfo = memberProfile(userId);

        BeanUtils.copyProperties(dto,userInfo);
        userInfo.setId(userId);
        userInfoRepository.save(userInfo);
        return userInfo;
    }

    public String memberProfileAvatarModify(String userId, MultipartFile file) {


        String fileName = file.getOriginalFilename();
        try {
            String bucketName = minioConfig.getBucketName();
            minioClientUtils.putObject(bucketName, file, fileName);
            String url = minioClientUtils.getObjectUrl(bucketName, fileName);
            UserInfo userInfo = memberProfile(userId);
            userInfo.setAvatar(url);
            userInfoRepository.save(userInfo);
            return url;
        } catch (Exception e) {
            log.error("上传失败 error ----> url: {}", fileName);
            return null;
        }
    }

    public Integer memberAddressAdd(String userId, AddressDTO dto) {

        Address address = new Address();
        BeanUtils.copyProperties(dto,address);
        address.setId(String.valueOf(keyGenerator.generateKey().longValue()));
        address.setUserId(userId);
        address = addressRepository.insert(address);
        if(address.getIsDefault() == 1){
            setOtherAddressNotDefault(userId, address.getId());
        }
        return 1;
    }

    public String memberAddressDelete(String userId, String id) {

        Address address = memberAddressDetail(userId, id);
        if(null!= address){
            addressRepository.deleteById(id);
            return id;
        }
        return null;
    }

    public Integer memberAddressModify(String userId, String id, AddressDTO dto) {
        Address address = memberAddressDetail(userId, id);
        if(null!= address){
            BeanUtils.copyProperties(dto,address);
            address.setId(id);
            address.setUserId(userId);
            addressRepository.save(address);
            if(address.getIsDefault() == 1){
                setOtherAddressNotDefault(userId, id);
            }
            return 1;
        }
        return null;
    }
    private void setOtherAddressNotDefault(String userId,String defaultId){

        List<Address> list = memberAddressList(userId).stream().filter(address -> !address.getId().equals(defaultId)).toList();
        for (Address address : list) {
            address.setIsDefault(0);
            addressRepository.save(address);
        }
    }

    public Address memberAddressDetail(String userId, String id) {

        Address address = addressRepository.findById(id).orElse(new Address());
        if(userId.equals(address.getUserId())){
            return address;
        }
        return null;
    }

    public List<Address> memberAddressList(String userId) {
        List<Address> list = addressRepository.findByUserId(userId);
        if(null == list){
            list = Lists.newArrayList();
        }
        return list;
    }

    public HotDetail hotPreference(String path,String subType, Integer page, Integer pageSize) {
        Pageable pageable = PageRequest.of(page-1, pageSize);
        List<HotDetail> list = shopHotDetailRepository.findByPath(path);
        HotDetail hotDetail = list.get(0);

        if(!StringUtils.hasLength(subType)){
            for (HotDetail.SubTypes type : hotDetail.getSubTypes()) {
                setHotDetailGoodsPage(pageable, type);
            }
        }else {
            for (HotDetail.SubTypes type : hotDetail.getSubTypes()) {
                if(type.getId().equals(subType)){
                    setHotDetailGoodsPage(pageable, type);
                }
            }
        }
        return hotDetail;
    }

    private void setHotDetailGoodsPage(Pageable pageable, HotDetail.SubTypes type) {
        String id = type.getId();
        Page<HotDetailGoods> result = shopHotDetailGoodsRepository.findBySubTypeId(id, pageable);
        PageVO<HotDetailGoods> pageVO = new PageVO<>();
        pageVO.setCount((int)result.getTotalElements());
        pageVO.setPageSize(result.getSize());
        pageVO.setPages(result.getTotalPages());
        pageVO.setPage(result.getNumber()+1);
        pageVO.setItems(result.getContent());
        if(!CollectionUtils.isEmpty(pageVO.getItems())){
            type.setGoodsItems(pageVO);
        }
    }

    public Cart cartAdd(String userId, CartAddDTO dto) {
        // 通过skuId 查询商品信息
        List<GoodsDetail> list = shopGoodsDetailRepository.findBySkusId(dto.getSkuId());
        if(!CollectionUtils.isEmpty(list)){
            GoodsDetail goodsDetail = list.getFirst();
            GoodsDetail.Sku sku = goodsDetail.getSkus().stream().filter(item -> item.getId().equals(dto.getSkuId())).findFirst().get();
            String attrsText = sku.getSpecs().stream().map(GoodsDetail.SpecSimple::getValueName).collect(Collectors.joining("， "));
            Cart cart = new Cart();
            cart.setCartId(String.valueOf(keyGenerator.generateKey().longValue()));
            cart.setUserId(userId);
            cart.setSkuId(dto.getSkuId());
            cart.setName(goodsDetail.getName());
            cart.setAttrsText(attrsText);
            cart.setSpecs(sku.getSpecs());
            cart.setPicture(sku.getPicture());
            cart.setPrice(sku.getPrice());
            cart.setNowPrice(sku.getPrice());
            cart.setSelected(Boolean.TRUE);
            if(sku.getInventory() < dto.getCount()){
                cart.setCount(sku.getInventory());
            }else {
                cart.setCount(dto.getCount());
            }
            cart.setStock(sku.getInventory());
            cart.setDiscount(goodsDetail.getDiscount());
            cart.setIsCollect(goodsDetail.getIsCollect());
            if(goodsDetail.getIsPreSale()){
                cart.setIsEffective(Boolean.FALSE);
            }else {
                cart.setIsEffective(Boolean.TRUE);
            }
            cart.setId(goodsDetail.getId());
            cart.setBuyStatus(Boolean.FALSE);
            return cartRepository.insert(cart);
        }

        return null;
    }

    public List<Cart> cartList(String userId) {
        return Optional.of(cartRepository.findByUserIdAndBuyStatus(userId,Boolean.FALSE)).orElse(Lists.newArrayList());
    }

    public Integer deleteCart(String userId, IdsDTO ids) {

       cartRepository.deleteByUserIdAndSkuIdIn(userId,ids.getIds());
        return 1;
    }

    public Cart modifyCart(String userId, CartModifyDTO dto) {

        List<Cart> list = cartRepository.findByUserIdAndBuyStatusAndSkuId(userId, Boolean.FALSE, dto.getSkuId());

        if (!CollectionUtils.isEmpty(list)){
            Cart cart = list.getFirst();
            if(dto.getSelected() ==null && dto.getCount() == null){
                return cart;
            }
            if(dto.getCount() != null){
                cart.setCount(dto.getCount());
            }
            if(dto.getSelected() != null){
                cart.setSelected(dto.getSelected());
            }
            return cartRepository.save(cart);
        }
        return null;
    }

    public Integer cartSelected(String userId, CartSelectedDTO dto) {
        List<Cart> list = cartRepository.findByUserIdAndBuyStatus(userId, Boolean.FALSE);
        if (!CollectionUtils.isEmpty(list)){
            list.forEach(cart -> cart.setSelected(dto.getSelected()));
            cartRepository.saveAll(list);
        }
        return null;
    }

    public OrderPreVO orderPre(String userId) {
        return orderPreAndCart(userId).getFirst();
    }

    private TwoValue<OrderPreVO,List<Cart>> orderPreAndCart(String userId) {

        List<OrderGoods> goods = Lists.newArrayList();
        List<Address> addressList = addressRepository.findByUserId(userId);
        List<Cart> cartList = Optional.of(cartRepository.findByUserIdAndBuyStatus(userId, Boolean.FALSE)).orElse(Lists.newArrayList()).stream().filter(Cart::getSelected).toList();
        OrderPreVO.Summary summary = new OrderPreVO.Summary();
        for (Cart cart : cartList) {
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setId(cart.getId());
            orderGoods.setName(cart.getName());
            orderGoods.setPicture(cart.getPicture());
            orderGoods.setCount(cart.getCount());
            orderGoods.setSkuId(cart.getSkuId());
            orderGoods.setAttrsText(cart.getAttrsText());
            orderGoods.setPrice(cart.getPrice());
            orderGoods.setPayPrice(cart.getNowPrice());
            orderGoods.setTotalPayPrice(new BigDecimal(cart.getCount()).multiply(new BigDecimal(cart.getNowPrice())).setScale(2, RoundingMode.HALF_UP).toString());
            orderGoods.setTotalPrice(new BigDecimal(cart.getCount()).multiply(new BigDecimal(cart.getPrice())).setScale(2, RoundingMode.HALF_UP).toString());
            goods.add(orderGoods);
            summary.setGoodsCount(summary.getGoodsCount() + cart.getCount());
            summary.setTotalPrice(new BigDecimal(orderGoods.getTotalPrice()).add(new BigDecimal(summary.getTotalPrice())).intValue());
            summary.setTotalPayPrice(new BigDecimal(orderGoods.getTotalPayPrice()).add(new BigDecimal(summary.getTotalPayPrice())).intValue());
        }
        summary.setTotalPayPrice(summary.getTotalPayPrice()+summary.getPostFee());

        OrderPreVO orderPreVO = new OrderPreVO();
        orderPreVO.setUserAddresses(addressList);
        orderPreVO.setGoods(goods);
        orderPreVO.setSummary(summary);
        return TwoValue.of(orderPreVO,cartList);
    }

    public Order orderCreate(String userId, OrderCreateDTO dto) {
        // 订单id
        String orderId = String.valueOf(keyGenerator.generateKey().longValue());
        // 获取现在时间 并转换为格式 yyyy-MM-dd HH:mm:ss 的字符串
        LocalDateTime now = LocalDateTimeUtil.now();
        LocalDateTime payLatestTime = LocalDateTimeUtil.now().plusMinutes(30);
        String createTime = LocalDateTimeUtil.format(now, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String payLatestStr = LocalDateTimeUtil.format(payLatestTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Duration duration = Duration.between(now, payLatestTime);
        long seconds = duration.getSeconds();
        Integer countdown =  seconds > 0 ? (int)seconds : -1;

        // 查询购物车 如果有需要更新购买状态
        TwoValue<OrderPreVO, List<Cart>> twoValue = orderPreAndCart(userId);
        OrderPreVO orderPreVO = twoValue.getFirst();
        // 获取地址详情
        Address address = orderPreVO.getUserAddresses().stream().filter(item -> item.getId().equals(dto.getAddressId())).findFirst().orElse(new Address());
        // 创建订单 返回订单id
        Order order = new Order();
        order.setId(orderId);
        order.setUserId(userId);
        order.setCreateTime(createTime);
        order.setPayLatestTime(payLatestStr);
        order.setCountdown(countdown);
        order.setPostFee(new BigDecimal(orderPreVO.getSummary().getPostFee()));
        order.setPayMoney(new BigDecimal(orderPreVO.getSummary().getTotalPayPrice()));
        order.setTotalMoney(new BigDecimal(orderPreVO.getSummary().getTotalPrice()));
        order.setTotalNum(orderPreVO.getSummary().getGoodsCount());
        order.setReceiverContact(address.getReceiver());
        order.setReceiverMobile(address.getContact());
        order.setProvinceCode(address.getProvinceCode());
        order.setCityCode(address.getCityCode());
        order.setCountyCode(address.getCountyCode());
        order.setReceiverAddress(address.getFullLocation()+address.getAddress());
        //  skus 字段
        order.setSkus(getOrderSkus(twoValue.getSecond()));
        orderRepository.insert(order);
        // 购物车标注已购买
        for (Cart cart : twoValue.getSecond()) {
            cart.setBuyStatus(Boolean.TRUE);
            cartRepository.save(cart);
        }
        return order;
    }

    private List<Order.OrderSku> getOrderSkus(List<Cart> cartList) {

        List<Order.OrderSku> list = Lists.newArrayList();
        for (Cart cart : cartList) {

            Order.OrderSku orderSku = new Order.OrderSku();
            orderSku.setId(cart.getSkuId());
            orderSku.setSpuId(cart.getId());
            orderSku.setName(cart.getName());
            orderSku.setQuantity(cart.getCount());
            orderSku.setImage(cart.getPicture());
            orderSku.setCurPrice(new BigDecimal(cart.getNowPrice()));
            orderSku.setRealPay(orderSku.getCurPrice().multiply(new BigDecimal(orderSku.getQuantity())));
            orderSku.setAttrsText(cart.getAttrsText());

            // 属性
            List<Order.Property> properties = Lists.newArrayList();
            for (GoodsDetail.SpecSimple spec : cart.getSpecs()) {
                Order.Property property = new Order.Property();
                property.setPropertyMainName(spec.getName());
                property.setPropertyValueName(spec.getValueName());
                properties.add(property);


            }
            orderSku.setProperties(properties);
            list.add(orderSku);
        }
        return list;
    }

    public String payMock(String userId, String orderId) {
        Optional<Order> optional = orderRepository.findById(orderId);
        if (optional.isPresent()){
            Order order = optional.get();
            LocalDateTime now = LocalDateTimeUtil.now();
            // 判断是否为待支付 判断是否超时
            if (order.getUserId().equals(userId)
                    && order.getOrderState() == 1
                    && now.isBefore(LocalDateTime.parse(order.getPayLatestTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))){
                order.setOrderState(2);
                order.setPayTime(LocalDateTimeUtil.format(now, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orderRepository.save(order);
                return "success";
            }
        }

        return "fail";
    }

    public OrderPreVO orderPreNow(String userId, Integer count, String skuId) {
        OrderPreVO orderPreVO = new OrderPreVO();
        List<OrderGoods> goods = Lists.newArrayList();
        OrderPreVO.Summary summary = new OrderPreVO.Summary();
        orderPreVO.setGoods(goods);
        orderPreVO.setUserAddresses(Lists.newArrayList());
        orderPreVO.setSummary(summary);

        // 通过skuId 查询商品信息
        List<GoodsDetail> list = shopGoodsDetailRepository.findBySkusId(skuId);
        if(!CollectionUtils.isEmpty(list)){
            GoodsDetail goodsDetail = list.getFirst();
            GoodsDetail.Sku sku = goodsDetail.getSkus().stream().filter(item -> item.getId().equals(skuId)).findFirst().get();
            String attrsText = sku.getSpecs().stream().map(GoodsDetail.SpecSimple::getValueName).collect(Collectors.joining("， "));

            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setId(goodsDetail.getId());
            orderGoods.setName(goodsDetail.getName());
            orderGoods.setPicture(sku.getPicture());
            orderGoods.setCount(count);
            orderGoods.setSkuId(skuId);
            orderGoods.setAttrsText(attrsText);
            orderGoods.setPrice(sku.getPrice());
            orderGoods.setPayPrice(sku.getPrice());
            orderGoods.setTotalPayPrice(new BigDecimal(orderGoods.getCount()).multiply(new BigDecimal(orderGoods.getPayPrice())).setScale(2, RoundingMode.HALF_UP).toString());
            orderGoods.setTotalPrice(new BigDecimal(orderGoods.getCount()).multiply(new BigDecimal(orderGoods.getPrice())).setScale(2, RoundingMode.HALF_UP).toString());
            goods.add(orderGoods);
            summary.setGoodsCount(summary.getGoodsCount() + orderGoods.getCount());
            summary.setTotalPrice(new BigDecimal(orderGoods.getTotalPrice()).add(new BigDecimal(summary.getTotalPrice())).intValue());
            summary.setTotalPayPrice(new BigDecimal(orderGoods.getTotalPayPrice()).add(new BigDecimal(summary.getTotalPayPrice())).intValue());


        }
        summary.setTotalPayPrice(summary.getTotalPayPrice()+summary.getPostFee());
        return orderPreVO;
    }

    public OrderPreVO orderRepurchase(String userId, String id) {
        Optional<Order> optional = orderRepository.findById(id);
        if (optional.isPresent()){

            OrderPreVO orderPreVO = new OrderPreVO();
            List<OrderGoods> goods = Lists.newArrayList();
            OrderPreVO.Summary summary = new OrderPreVO.Summary();
            orderPreVO.setGoods(goods);
            orderPreVO.setUserAddresses(Lists.newArrayList());
            orderPreVO.setSummary(summary);

            Order order = optional.get();
            List<Order.OrderSku> skus = order.getSkus();
            for (Order.OrderSku orderSku : skus) {
                OrderPreVO item = orderPreNow(userId, orderSku.getQuantity(), orderSku.getId());
                summary.setGoodsCount(summary.getGoodsCount() + item.getSummary().getGoodsCount());
                summary.setTotalPrice(summary.getTotalPrice() + item.getSummary().getTotalPrice());
                summary.setTotalPayPrice(summary.getTotalPayPrice() + new BigDecimal(item.getGoods().get(0).getTotalPayPrice()).intValue());

                goods.addAll(item.getGoods());
            }
            summary.setTotalPayPrice(summary.getTotalPayPrice()+summary.getPostFee());
            return orderPreVO;

        }
        return null;
    }

    /**
     * 订单发货
     * 仅在 订单状态为待发货 时，可模拟发货，调用后订单状态修改为待收货，包含模拟物流
     */
    public String orderConsignment(String userId, String id) {
        Optional<Order> optional = orderRepository.findById(id);
        if(optional.isPresent()){
            Order order = optional.get();
            if (userId.equals(order.getUserId()) && order.getOrderState() == 2){
                order.setOrderState(3);
                LocalDateTime now = LocalDateTimeUtil.now();
                order.setConsignTime(LocalDateTimeUtil.format(now, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                order.setArrivalEstimatedTime(LocalDateTimeUtil.format(now.plusDays(5), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                orderRepository.save(order);
                return order.getId();
            }
        }
        return "fail";
    }

    /**
     * 确认收货
     * 仅在订单状态为待收货时，可确认收货。
     */
    public Order orderReceipt(String userId, String id) {
        Optional<Order> optional = orderRepository.findById(id);
        if(optional.isPresent()){
            Order order = optional.get();
            if (userId.equals(order.getUserId()) && order.getOrderState() == 3){
                order.setOrderState(4);
//                order.setEndTime(LocalDateTimeUtil.format(LocalDateTimeUtil.now(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                return orderRepository.save(order);
            }
        }
        return new Order();
    }

    public LogisticsVO orderLogistics(String userId, String id) {
        Optional<Order> optional = orderRepository.findById(id);
        if(optional.isPresent()){
            Order order = optional.get();
            if (userId.equals(order.getUserId()) && Lists.newArrayList(3,4,5).contains(order.getOrderState())){

                return LogisticsVO.getLogisticsVO(order.getTotalNum(), order.getSkus().get(0).getImage(), order.getConsignTime());
            }
        }
        return new LogisticsVO();
    }

    /**
     * 删除订单
     * 仅在订单状态为待评价，已完成，已取消时，可删除订单。
     */
    public Integer orderDelete(String userId,IdsDTO ids) {
        if (!ids.getIds().isEmpty()){
            List<Order> orders = orderRepository.findAllById(ids.getIds());
            orders.forEach(order -> {
                if (userId.equals(order.getUserId()) && Lists.newArrayList(4,5,6).contains(order.getOrderState())){
                    orderRepository.deleteById(order.getId());
                }
            });
            return 1;
        }
        return 0;
    }

    /**
     * 取消订单
     * 仅在订单状态为待付款时，可取消订单。
     */
    public Order orderCancel(String userId, String id) {
        Optional<Order> optional = orderRepository.findById(id);
        if(optional.isPresent()){
            Order order = optional.get();
            if (userId.equals(order.getUserId()) && order.getOrderState() == 1){
                order.setOrderState(6);
                return orderRepository.save(order);
            }
        }
        return new Order();
    }

    public PageVO<Order> orderPage(String userId, Integer orderState, Integer page, Integer pageSize) {

        // mongoDB 分页 page 是从0开始
        Pageable pageable = PageRequest.of(page-1, pageSize);
        Page<Order> result;
        if (orderState != null && orderState > 0){
            /*String jsonStr = JSON.toJSONString(orderRepository.findByUserIdAndOrderStateNative(userId, orderState,pageSize,page-1));
            System.out.println(jsonStr);*/

            result = orderRepository.findByUserIdAndOrderState(userId, orderState, pageable);
        }else {
            result = orderRepository.findByUserId(userId, pageable);
        }
        PageVO<Order> pageVO = new PageVO<>();
        pageVO.setCount((int)result.getTotalElements());
        pageVO.setPageSize(result.getSize());
        pageVO.setPages(result.getTotalPages());
        pageVO.setPage(result.getNumber()+1);
        pageVO.setItems(result.stream().toList());
        return pageVO;
    }

    public Order orderDetail(String userId, String id) {

        LocalDateTime now = LocalDateTimeUtil.now();
        Optional<Order> optional = orderRepository.findById(id);
        if (optional.isPresent()){
            Order order = optional.get();
            if(userId.equals(order.getUserId())){
                if(order.getOrderState()==1){
                    Duration duration = Duration.between(now, LocalDateTime.parse(order.getPayLatestTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    long seconds = duration.getSeconds();
                    Integer countdown =  seconds > 0 ? (int)seconds : -1;
                    order.setCountdown(countdown);
                }
                return order;
            }
        }
        return new Order();
    }
}
